package com.katze.boot.plugins.security.service;

import com.katze.boot.plugins.security.annotations.Logical;
import com.katze.boot.plugins.security.annotations.RestRequestMapping;
import com.katze.boot.plugins.security.domain.RootObject;
import com.katze.boot.plugins.security.domain.UserDetail;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.util.AntPathMatcher;

@Service("ps")
public class PermissionService {
    private final AntPathMatcher antPathMatcher = new AntPathMatcher();

    public boolean hasPermission(String permission) {
        UserDetail user = (UserDetail) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        for (String item : user.getPermissions()) {
            if (antPathMatcher.match(item, permission)) {
                return true;
            }
        }
        return false;
    }

    public boolean toAuthority(RootObject root){
        MethodInvocation methodInvocation = root.getMethodInvocation();
        if (methodInvocation == null) {
            return true;
        }
        RestRequestMapping annotation = methodInvocation.getMethod().getAnnotation(RestRequestMapping.class);
        if (annotation == null) {
            return true;
        }

        String[] authorities = annotation.permits();
        if (authorities.length == 1 && authorities[0].isEmpty()){
            return true;
        }

        UserDetail user = (UserDetail) root.getPrincipal();
        if (user == null) {
            return false;
        }


        if (Logical.AND == annotation.logical()) {
            for (String authority : authorities) {
                if (!user.getPermissions().contains(authority)) {
                    return false;
                }
            }
            return true;
        } else {
            for (String authority : authorities) {
                if (user.getPermissions().contains(authority)) {
                    return true;
                }
            }
            return false;
        }
    }
}
